//
// Created by konglinglong on 2020/9/11.
//

#ifndef O5G_SRC_O5GRAN_L3_INCLUDE_L3DEF_H
#define O5G_SRC_O5GRAN_L3_INCLUDE_L3DEF_H

#include "../../../../lib/csp/include/cspApi.h"
#include "../../include/ranApi.h"
#include "../../lcore/include/commDef.h"

typedef enum
{
    RAN_L3_UE_SM_STATE_IDLE,
    RAN_L3_UE_SM_STATE_BUTT
} E_RanL3UeSmState;

typedef enum
{
    RAN_L3_UE_SM_EVENT_IDLE,
    RAN_L3_UE_SM_EVENT_BUTT
} E_RanL3UeSmEvent;

typedef struct RanL3UeInst
{
    uint32_t inUse;
    uint32_t ueId;

    uint32_t nbIdx;
    uint32_t cellIdx;
    uint32_t ueIdx;

    E_RanL3UeSmState state;
    S_FsmInst *ueSmInst;
} S_RanL3UeInst;

typedef enum
{
    RAN_L3_CELL_SM_STATE_INIT,
    RAN_L3_CELL_SM_STATE_WAIT_L1_PARAMS_RSP,
    RAN_L3_CELL_SM_STATE_WAIT_L1_CONFIG_RSP,
    RAN_L3_CELL_SM_STATE_WAIT_L2_CONFIG_RSP,
    RAN_L3_CELL_SM_STATE_WAIT_L1_START_RSP,
    RAN_L3_CELL_SM_STATE_WAIT_L2_START_RSP,
    RAN_L3_CELL_SM_STATE_WAIT_L2_MIB_TX_RSP,
    RAN_L3_CELL_SM_STATE_CELL_SETUP_SUCC,
    RAN_L3_CELL_SM_STATE_BUTT
} E_RanL3CellSmState;

typedef enum
{
    RAN_L3_CELL_SM_EVENT_CELL_SETUP_TRIGGER,
    RAN_L3_CELL_SM_EVENT_RECV_L1_PARAMS_RSP,
    RAN_L3_CELL_SM_EVENT_RECV_L1_CONFIG_RSP,
    RAN_L3_CELL_SM_EVENT_RECV_L2_CONFIG_RSP,
    RAN_L3_CELL_SM_EVENT_RECV_L1_START_RSP,
    RAN_L3_CELL_SM_EVENT_RECV_L2_START_RSP,
    RAN_L3_CELL_SM_EVENT_RECV_L2_MIB_TX_RSP,
    RAN_L3_CELL_SM_EVENT_BUTT
} E_RanL3CellSmEvent;

typedef struct RanL3CellInst
{
    uint32_t inUse;
    uint32_t cellId;

    uint32_t nbIdx;
    uint32_t cellIdx;

    E_RanL3CellSmState state;
    S_FsmInst *cellSmInst;
    uint8_t mibBuffer[3]; // 24bit
    uint32_t mibSize;

    uint32_t ueNum;
    S_RanL3UeInst ueInst[RAN_UE_NUM_MAX];
} S_RanL3CellInst;

typedef enum
{
    RAN_L3_NB_SM_STATE_INIT,
    RAN_L3_NB_SM_STATE_WAIT_SCTP_SETUP_SUCC,
    RAN_L3_NB_SM_STATE_WAIT_NGAP_SETUP_RSP,
    RAN_L3_NB_SM_STATE_NGAP_SETUP_SUCC,
    RAN_L3_NB_SM_STATE_BUTT
} E_RanL3NbSmState;

typedef enum
{
    RAN_L3_NB_SM_EVENT_SCTP_SETUP_TRIGGER,
    RAN_L3_NB_SM_EVENT_RECV_NGAP_SETUP_RSP,
    RAN_L3_NB_SM_EVENT_BUTT
} E_RanL3NbSmEvent;

typedef struct RanL3NbInst
{
    uint32_t inUse;
    uint32_t nbId;

    uint32_t nbIdx;

    S_O5gPlmnIdAdpt plmn;
    S_O5gIpStr amfIp;
    S_O5gIpStr upfIp;
    int sctpFd;
    E_RanL3NbSmState state;
    S_FsmInst *nbSmInst;
    uint32_t cellNum;
    S_RanL3CellInst cellInst[RAN_CELL_NUM_MAX];
} S_RanL3NbInst;

typedef struct RanL3Context
{
    pthread_t tid;
    uint64_t tick10ms;
    S_OsSelect selector;
    int l2SockFd;
    S_Poller *poller;
    S_Fsm *nbFsm;
    S_Fsm *cellFsm;
    S_Fsm *ueFsm;
    S_FixRingBuffer *nbFsmEvtQue;
    S_FixRingBuffer *cellFsmEvtQue;
    S_FixRingBuffer *ueFsmEvtQue;

    uint32_t nbNum;
    S_RanL3NbInst nbInst[RAN_NODEB_NUM_MAX];
    char sockRecvBuffer[SOCK_BUFFER_SIZE];
} S_RanL3Context;

extern S_RanL3Context *gpRanL3Context;

#endif //O5G_SRC_O5GRAN_L3_INCLUDE_L3DEF_H
